package com.gitee.wsl.func.filter.sample

import com.gitee.wsl.ext.array.bytes.toInt
import com.gitee.wsl.func.filter.StringFilter
import com.gitee.wsl.lang.bits.BitSet
import com.gitee.wsl.security.hash.MD5
import com.gitee.wsl.security.hash.HasherFactory
import com.gitee.wsl.security.hash.hash

class BloomFilter2(
    private val bitfieldSize: Int,
    private vararg val hashAlgorithm: HasherFactory
): StringFilter {
    constructor() : this(1024, MD5)

    private val bitField = BitSet(bitfieldSize)

    fun add(word: String) {
        word.ifEmpty { throw IllegalArgumentException() }
        hashAlgorithm.forEach { bitField.set(word.encodeToByteArray().hash(it).bytes.toInt() % bitfieldSize) }
    }

    fun add(wordList: Set<String>) {
        wordList.forEach { add(it) }
    }

    internal fun isProbablyKnown(word: String): Boolean {
        return hashAlgorithm.all { bitField[word.encodeToByteArray().hash(it).bytes.toInt() % bitfieldSize] }
    }

    override fun filter(para: String): Boolean = isProbablyKnown(para)
}